package cn.zhou.basic.service.impl;

import cn.zhou.basic.BaseConstant;
import cn.zhou.basic.dto.RegisterDto;
import cn.zhou.basic.exception.BusinessException;
import cn.zhou.basic.service.IVerifyCodeService;
import cn.zhou.basic.util.StrUtils;
import cn.zhou.basic.util.VerifyCodeUtils;
import cn.zhou.user.domain.User;
import cn.zhou.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Override
    public String ImageCode(String key) throws Exception {
        if(!StringUtils.hasLength(key)){
            throw new BusinessException("滚滚滚");
        }
        // 这里是生成code 显示码的个数以及拿到
        String code = StrUtils.getComplexRandomString(5);
        // 保存redis，设置过期时间  key是什么==前端请求给我传递的UUID
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        System.out.println("redisTemplate"+redisTemplate.opsForValue().get(key));
        return VerifyCodeUtils.VerifyCode(100,40,code);
        // 上面是得到图形验证码
    }


    /**
     * 一：校验
     *  1.空校验
     *  2.校验图形验证码，根据imageCodeKey从redis获取图形验证码
     *   。获取不到 图形验证码过期，重新获取
     *   。获取到了，比对图形验证码是否正确
     * 	  - 不正确，提示输入图形验证码错误
     * 	  - 正确，往下走
     *  3.校验手机号是否注册过了
     *   。注册过了，滚去登录
     *   。没有注册过，往下走
     * 二：短信验证码逻辑
     *  1.根据手机号拼接key，159:register，从redis获取曾今可能发送的短信验证码
     *   1.1 获取到了
     *     1.1.1 校验是否过了一分钟重发时间 value  9527:232468742341657213
     * 	   。小于一分钟  哥屋恩
     * 	   。大于一分中 （还没有到3分钟，验证码还有效），
     * 	       使用还没过期的验证码，刷新过期时间
     *   1.2 获取不到
     *      1.2.1.生成新的短信验证码
     *
     *  3.存储redis 设置一个过期时间
     *  4.发送短信
     * @param dto
     */
    @Override
    public void SmsCode(RegisterDto dto) {
        String imageCodeKey = dto.getImageCodeKey();
        String imageCodeValue = dto.getImageCodeValue();
        String phone = dto.getPhone();

        //1.下面写 短信的方式 填入图片验证码，判断是否为空 填的手机号码是否为空，首先验证是否为空
        if(StringUtils.isEmpty(imageCodeKey)||
                StringUtils.isEmpty(imageCodeValue)||
                StringUtils.isEmpty(phone)){
            throw new BusinessException("不能是空哦");
        }
        //如果都正确，那么验证填写的图片验证码和系统的比较，不同就撵走，  还有可能就是时间过了 需要重新发送
        //2.校验图形验证码，根据imageCodeKey从redis获取图形验证码
        Object imageCodeTmp  = redisTemplate.opsForValue().get(imageCodeKey);
        if(imageCodeTmp ==null){
            throw new BusinessException("失效了，大哥动作快点");
        }
        // 那么验证填写的图片验证码和系统的比较，不同就撵走 这里需要不区分大小写   如果是正确的就执行下面
        if(!imageCodeTmp.toString().equalsIgnoreCase(imageCodeValue)){
            throw new BusinessException("大哥，你输入错了，认真点");
        }
        /**若是对得上那就走下面，下面就判断密码和再写密码是否相等 验证手机号是否注册过
         * 这里把前端页面拿到的phone 放进user表中查询， 看看有不有数据，有就证明了，已经存在，没有就可以新建
        */
        User byphone = userMapper.loadByphone(phone);
        if(byphone!=null){
            throw new BusinessException("大哥,你已经谁会员了，这里满足不了你，来前面");
        }
        //以上全是校验
        // 下面是发送短信的罗技
//                1.根据手机号拼接key，159:register，从redis获取曾今可能发送的短信验证 前端传一个号码，我们拼接
                    // 格式  电话 +"xxxxx" 拿key 和value   把填写的验证码拼接
                String key =BaseConstant.RegisterConstants.REGISTER_SMS_PREFIX+phone ;
                    // 获取到拼接好的验证码
                Object getkeys = redisTemplate.opsForValue().get(key);
//                *   1.1 获取到了 为null 就不能到这一步
                String smsCode = "";
                if(getkeys!=null){
                    // 判断是否超时了   转换类型
                   //  1.1.1 校验是否过了一分钟重发时间 value  9527:232468742341657213
//                 	   。小于一分钟  哥屋恩
                    Long oldtime = Long.valueOf(getkeys.toString().split(":")[1]);
                    if(System.currentTimeMillis()-oldtime<=1*60*1000){
                        throw new BusinessException("哪里凉快去那里");
                    }
                    //大于一分中 （还没有到3分钟，验证码还有效）， 使用还没过期的验证码，刷新过期时间
                     smsCode=getkeys.toString().split(":")[0];
                }else {
                    //   1.2 获取不到
                    //    1.2.1.生成新的短信验证码
                    smsCode = StrUtils.getComplexRandomString(5);
                }
//                *  3.存储redis 设置一个过期时间    拼接一个新的  然后再设置过期时间
                String smsCodeValue = smsCode + ":"+ System.currentTimeMillis();
                redisTemplate.opsForValue().set(
                        key,
                        smsCodeValue,
                        3,
                        TimeUnit.MINUTES);

        //                *  4.发送短信
                System.out.println("亲，您的验证码是：" + smsCode + "。请在3分钟内使用！！");

    }


}
